/*
 * Copyright 2023, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#include "AntCalendarView.h"

#include <Catalog.h>
#include <LayoutBuilder.h>
#include <GroupLayout.h>
#include <StringFormat.h>
#include <Window.h>

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "AntCalendarView"

// 消息常量
const uint32 kMsgPrevMonth = 'prvM';
const uint32 kMsgNextMonth = 'nxtM';
const uint32 kMsgDaySelected = 'dayS';


AntCalendarView::AntCalendarView(const char* name)
	:
	BView(name, B_WILL_DRAW),
	fDayLabels(NULL),
	fDayButtons(NULL),
	fCurrentYear(0),
	fCurrentMonth(0),
	fCurrentDay(0),
	fSelectedYear(0),
	fSelectedMonth(0),
	fSelectedDay(0)
{
	// 获取当前日期
	BDateTime now = BDateTime::CurrentDateTime(B_LOCAL_TIME);
	BDate today = now.Date();
	fCurrentYear = today.Year();
	fCurrentMonth = today.Month();
	fCurrentDay = today.Day();
	fSelectedYear = fCurrentYear;
	fSelectedMonth = fCurrentMonth;
	fSelectedDay = fCurrentDay;
	
	// 初始化界面
	_InitInterface();
}


AntCalendarView::~AntCalendarView()
{
	// 释放动态分配的内存
	if (fDayLabels != NULL) {
		for (int i = 0; i < 7; i++)
			delete fDayLabels[i];
		delete[] fDayLabels;
	}
	
	if (fDayButtons != NULL) {
		for (int i = 0; i < 42; i++)
			delete fDayButtons[i];
		delete[] fDayButtons;
	}
}


void
AntCalendarView::AttachedToWindow()
{
	BView::AttachedToWindow();
	
	// 设置控件的目标为此视图
	fPrevMonthButton->SetTarget(this);
	fNextMonthButton->SetTarget(this);
	
	for (int i = 0; i < 42; i++)
		fDayButtons[i]->SetTarget(this);
	
	// 更新日历显示
	_UpdateCalendar();
}


void
AntCalendarView::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case kMsgPrevMonth:
		{
			// 切换到上一个月
			fSelectedMonth--;
			if (fSelectedMonth < 1) {
				fSelectedMonth = 12;
				fSelectedYear--;
			}
			_UpdateCalendar();
			break;
		}
		
		case kMsgNextMonth:
		{
			// 切换到下一个月
			fSelectedMonth++;
			if (fSelectedMonth > 12) {
				fSelectedMonth = 1;
				fSelectedYear++;
			}
			_UpdateCalendar();
			break;
		}
		
		case kMsgDaySelected:
		{
			// 处理日期选择
			int32 day;
			if (message->FindInt32("day", &day) == B_OK) {
				fSelectedDay = day;
				_UpdateCalendar();
			}
			break;
		}
		
		default:
			BView::MessageReceived(message);
			break;
	}
}


void
AntCalendarView::_InitInterface()
{
	// 创建月份和年份显示
	fMonthYearView = new BStringView("monthYear", "");
	fMonthYearView->SetFont(be_bold_font);
	
	// 创建导航按钮
	fPrevMonthButton = new BButton("prevMonth", "◀", new BMessage(kMsgPrevMonth));
	fNextMonthButton = new BButton("nextMonth", "▶", new BMessage(kMsgNextMonth));
	
	// 创建星期标签
	fDayLabels = new BStringView*[7];
	const char* weekdays[] = {"日", "一", "二", "三", "四", "五", "六"};
	for (int i = 0; i < 7; i++) {
		BString name;
		name.SetToFormat("weekday%d", i);
		fDayLabels[i] = new BStringView(name.String(), weekdays[i]);
		fDayLabels[i]->SetAlignment(B_ALIGN_CENTER);
	}
	
	// 创建日期按钮
	fDayButtons = new BButton*[42]; // 6行 x 7列
	for (int i = 0; i < 42; i++) {
		BString name;
		name.SetToFormat("day%d", i);
		
		BMessage* message = new BMessage(kMsgDaySelected);
		message->AddInt32("day", i);
		
		fDayButtons[i] = new BButton(name.String(), "", message);
		fDayButtons[i]->SetFlat(true);
	}
	
	// 创建布局
	BGroupLayout* topLayout = new BGroupLayout(B_VERTICAL, 0);
	SetLayout(topLayout);
	
	// 添加月份导航栏
	BLayoutBuilder::Group<>(topLayout)
		.AddGroup(B_HORIZONTAL)
			.Add(fPrevMonthButton)
			.Add(fMonthYearView)
			.Add(fNextMonthButton)
		.End()
		.AddStrut(5);
	
	// 创建日历网格
	fCalendarGrid = new BGridLayout();
	topLayout->AddItem(fCalendarGrid);
	
	// 添加星期标签
	for (int i = 0; i < 7; i++)
		fCalendarGrid->AddView(fDayLabels[i], i, 0);
	
	// 添加日期按钮
	for (int row = 0; row < 6; row++) {
		for (int col = 0; col < 7; col++) {
			int index = row * 7 + col;
			fCalendarGrid->AddView(fDayButtons[index], col, row + 1);
		}
	}
}


void
AntCalendarView::_UpdateCalendar()
{
	// 更新月份和年份显示
	_UpdateMonthYear();
	
	// 计算当月第一天是星期几
	BDate firstDay(fSelectedYear, fSelectedMonth, 1);
	int firstDayOfWeek = firstDay.DayOfWeek();
	
	// 计算当月有多少天
	int daysInMonth;
	switch (fSelectedMonth) {
		case 2: // 二月
			daysInMonth = (fSelectedYear % 4 == 0 && 
				(fSelectedYear % 100 != 0 || fSelectedYear % 400 == 0)) ? 29 : 28;
			break;
		case 4: case 6: case 9: case 11: // 30天的月份
			daysInMonth = 30;
			break;
		default: // 31天的月份
			daysInMonth = 31;
			break;
	}
	
	// 更新日期按钮
	for (int i = 0; i < 42; i++) {
		int day = i - firstDayOfWeek + 1;
		
		if (day > 0 && day <= daysInMonth) {
			// 显示当月日期
			BString dayText;
			dayText.SetToFormat("%d", day);
			
			// 获取农历日期
			BString lunarDate;
			_GetLunarDate(fSelectedYear, fSelectedMonth, day, lunarDate);
			
			// 组合公历和农历显示
			dayText.Append("\n");
			dayText.Append(lunarDate);
			
			fDayButtons[i]->SetLabel(dayText.String());
			fDayButtons[i]->SetEnabled(true);
			
			// 高亮显示当前日期
			if (fSelectedYear == fCurrentYear && 
				fSelectedMonth == fCurrentMonth && 
				day == fCurrentDay) {
				fDayButtons[i]->SetFlat(false);
			} else {
				fDayButtons[i]->SetFlat(true);
			}
		} else {
			// 隐藏非当月日期
			fDayButtons[i]->SetLabel("");
			fDayButtons[i]->SetEnabled(false);
		}
	}
}


void
AntCalendarView::_UpdateMonthYear()
{
	// 月份名称
	const char* monthNames[] = {
		"一月", "二月", "三月", "四月", "五月", "六月",
		"七月", "八月", "九月", "十月", "十一月", "十二月"
	};
	
	// 更新月份和年份显示
	BString monthYearText;
	monthYearText.SetToFormat("%s %d", monthNames[fSelectedMonth - 1], fSelectedYear);
	fMonthYearView->SetText(monthYearText.String());
}


void
AntCalendarView::_GetLunarDate(int year, int month, int day, BString& lunarDate)
{
	// 简化版农历转换，实际应用中应使用完整的农历算法
	// 这里仅作为示例，返回简单的农历日期表示
	
	// 农历日期名称
	const char* lunarDays[] = {
		"初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
		"十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
		"廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"
	};
	
	// 简单模拟农历日期，实际应用中需要使用准确的农历转换算法
	int lunarDay = (day + month + year) % 30;
	lunarDate = lunarDays[lunarDay];
}